package cn.qianxun.meta.common.core.manager;

import cn.qianxun.meta.common.core.config.scheduled.WrappingScheduledExecutor;
import cn.qianxun.meta.common.core.thread.ThreadPool;
import cn.qianxun.meta.common.core.thread.Threads;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 异步任务管理器
 *
 * @author fuzhilin
 */
public class AsyncManager {

    private static final Logger log = LoggerFactory.getLogger(AsyncManager.class);
    /**
     * 操作延迟10毫秒
     */
    private final int OPERATE_DELAY_TIME = 10;

    public static final int CORE_POPL_SIZE = 4;
    /**
     * 异步操作任务调度线程池
     */
    private final ScheduledExecutorService executor = new ScheduledThreadPoolExecutor(CORE_POPL_SIZE,
            new BasicThreadFactory.
                    Builder().namingPattern("common-schedule-pool-%d").daemon(true).build());

    private ScheduledExecutorService scheduledExecutorService = null;

    private ExecutorService executorService = ThreadPool.newCachedThreadPool();

    /**
     * 单例模式
     */
    private AsyncManager() {
    }

    private static final AsyncManager me = new AsyncManager();

    public static AsyncManager me() {
        return me;
    }

    private ScheduledExecutorService getScheduledExecutorService() {
        scheduledExecutorService = new WrappingScheduledExecutor(50,
                new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build()) {
            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                super.afterExecute(r, t);
                Threads.printException(r, t);
            }
        };
        return scheduledExecutorService;
    }

    /**
     * 执行任务
     *
     * @param task 任务
     */
    public void execute(TimerTask task) {
        try {
            scheduledExecutorService = getScheduledExecutorService();
            if (executor.isShutdown() || executor.isTerminated()) {
                if (scheduledExecutorService == null || scheduledExecutorService.isShutdown() || scheduledExecutorService.isTerminated()) {
                    scheduledExecutorService = getScheduledExecutorService();
                }
                scheduledExecutorService.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
            } else {
                executor.schedule(task, OPERATE_DELAY_TIME, TimeUnit.MILLISECONDS);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 停止任务线程池
     */
    public void shutdown() {
        log.info("关闭线程池--------");
        Threads.shutdownAndAwaitTermination(executor);
    }
}
